#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import print_function
import sys, types, logging, time, datetime
import urllib2, cookielib, socket, httplib, ssl
from email.utils import parsedate
import xml.etree.ElementTree as et
import re

class PooledHttpHandler(urllib2.HTTPHandler, urllib2.HTTPSHandler):
    def __init__(self):
        urllib2.AbstractHTTPHandler.__init__(self)
        self.pool = dict()
    def _open(self, http_class, req):
        host = req.get_host()
        if not host:
            raise URLError('no host given')
        host += req._tunnel_host if req._tunnel_host else ""
        tryed = 0
        while  tryed < 5:
            if self.pool.has_key(host) and self.pool[host].sock:
                con = self.pool[host]
            else:
                con = self.make_con(http_class,req)
                self.pool[host] = con
            try:
                return self.do_open(con,req)
            except (ssl.SSLError, socket.timeout,httplib.HTTPException):
                con.close()
                del self.pool[host]
                tryed += 1
        raise httplib.HttpException()

    def http_open(self, req):
        return self._open(httplib.HTTPConnection, req)
    def https_open(self, req):
        return self._open(httplib.HTTPSConnection, req)
    https_request = urllib2.AbstractHTTPHandler.do_request_
    http_request = urllib2.AbstractHTTPHandler.do_request_
    
    def make_con(self,http_class, req):
        host = req.get_host()
        if not host:
            raise URLError('no host given')
        http = http_class(host, timeout=req.timeout) # will parse host:port
        http.set_debuglevel(self._debuglevel)
        return http
        
    def do_open(self, http, req):
        """Return an addinfourl object for the request, using http_class.

        http_class must implement the HTTPConnection API from httplib.
        The addinfourl return value is a file-like object.  It also
        has methods and attributes including:
            - info(): return a mimetools.Message object for the headers
            - geturl(): return the original request URL
            - code: HTTP status code
        """
        headers = dict(req.unredirected_hdrs)
        headers.update(dict((k, v) for k, v in req.headers.items()
                            if k not in headers))
        headers = dict(
            (name.title(), val) for name, val in headers.items())

        if req._tunnel_host:
            tunnel_headers = {}
            proxy_auth_hdr = "Proxy-Authorization"
            if proxy_auth_hdr in headers:
                tunnel_headers[proxy_auth_hdr] = headers[proxy_auth_hdr]
                # Proxy-Authorization should not be sent to origin
                # server.
                del headers[proxy_auth_hdr]
            http.set_tunnel(req._tunnel_host, headers=tunnel_headers)

        try:
            http.request(req.get_method(), req.get_selector(), req.data, headers)
        except socket.error, err: # XXX what error?
            http.close()
            raise URLError(err)
        else:
            try:
                resp = http.getresponse(buffering=True)
            except TypeError: # buffering kw not supported
                resp = http.getresponse()
        
        resp.recv = resp.read
        fp = socket._fileobject(resp, close=True)

        resp2 = urllib2.addinfourl(fp, resp.msg, req.get_full_url())
        resp2.code = resp.status
        resp2.msg = resp.reason
        resp2.data = resp.read()
        if hasattr(self, 'on_response'):
            self.on_response(resp)
        return resp2

class HttpClient(object):
    def __init__(self, timeout = 5.0):
        self.cookies = cookielib.CookieJar()
        phandler = PooledHttpHandler()
        phandler.on_response = self.on_response
        self.opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(self.cookies), phandler)
        self.timeout = timeout
    def on_response(self,resp):
        date = resp.getheader('Date')
        self.time = datetime.datetime(*parsedate(date)[:6]) + datetime.timedelta(seconds=-time.timezone)
    def debug_cookie(self):
        for x in self.cookies:
            print(x)
    def request(self,*arg, **karg):
        req = urllib2.Request(*arg,**karg)
        return req
    def open(self, req):
        return self.opener.open(req, timeout=self.timeout)
            
class CibClient(HttpClient):
    def __init__(self):
        super(CibClient,self).__init__();
        self.host = "3g.clib.com.cn"
    def _request(self, url, data= None, **hdrs):
        headers = {"User-Agent":"Mozilla/5.0 Gecko/20100101 Firefox/22.0",
                   "Accept-Encoding": "gzip, deflate",
                   "Connection": "keep-alive"
                   }
        headers.update(hdrs)
        req = self.request(url,origin_req_host=self.host,headers= headers, data= data)
        return req
    def pre_auth(self):
        req = self._request("https://3g.cib.com.cn/app/00002.html?flowsn=204")
        res = self.open(req)
        data = res.data
        data = data.strip()
        #self.loginpage = et.fromstring(data)
    def auth(self):
        #flowsn=402&pwd=adonis&loginname=univert&req_zjhm=294011&passwd=adonis
        req = self._request("https://3g.cib.com.cn/app/00002.html", data = "flowsn=402&pwd=adonis&loginname=univert&req_zjhm=294011&passwd=adonis")
        res = self.open(req)
        data = res.data
        if re.search("继续",data):
            req = self._request("https://3g.cib.com.cn/app/00002.html", data="flowsn=24")
            res = self.open(req)
            ata = re.search("账户查询",res.data)
        pass
    def do_pre_buy(self):
        req = self._request("https://3g.cib.com.cn/app/20071.html", "secmenu=0000000362", Referer="https://3g.cib.com.cn/app/20070.html")
        res = self.open(req)
        data = res.data        
        reqId = re.search(r'name="reqId".*value="([^"]+)"',data).group(1)
        data = self.open(self._request("https://3g.cib.com.cn/app/21000.html",
                         'flowsn=3&doyzm=0&reqId={}&currAcc=21624245511&listno=0&pwd=431768&yzmkey=&submit=%E7%A1%AE%E8%AE%A4'.format(reqId),
                         Referer="https://3g.cib.com.cn/app/20071.html")
                         ).data
        data
    def do_sell(self):
        data = None
        try:
            req = self._request("https://3g.cib.com.cn/app/20072.html ", "secmenu=0000000363", Referer="https://3g.cib.com.cn/app/20070.html")
            data = self.open(req).data
            fundid = re.search(r'产品编号.*?>(\d+)<', data, re.DOTALL).group(1)
            if not fundid: return False
            print(fundid)
            req = self._request("https://3g.cib.com.cn/app/20072.html", "flowsn=6&cpdh={}".format(fundid), Referer="https://3g.cib.com.cn/app/21000.html")
            data = self.open(req).data
            amt = re.search(r'可用份额.*?([\d\.]+)', data, re.DOTALL).group(1)
            if amt <= 1.0: return False
            req = self._request("https://3g.cib.com.cn/app/20072.html", "flowsn=10&shfe={}&submit=%E7%A1%AE%E8%AE%A4".format(amt), Referer="https://3g.cib.com.cn/app/20072.html")
            data = self.open(req).data
            reqId = re.search(r'name="reqId".*value="([^"]+)"',data).group(1)
            req = self._request("https://3g.cib.com.cn/app/20072.html", "flowsn=12&reqId={}&b0=%E7%A1%AE%E8%AE%A4".format(reqId), Referer="https://3g.cib.com.cn/app/20072.html")
            data = self.open(req).data
            if re.search("业务编",data):
                return True
        except:
            return False
        print(data)
        return False
        
def main(argv):
    cib = CibClient()
    cib.pre_auth()
    cib.auth()
    cib.do_pre_buy()
    ret = cib.do_sell()
    return 0 if ret else 1

class MyFileHandler(logging.FileHandler):
    def __init__(self, *argv, **kargv):
        super(MyFileHandler,self).__init__(*argv, **kargv)
        self.close()
        self.stream = None
    def emit(self, record):
        self.stream = self._open()
        super(MyFileHandler,self).emit(record)
        self.close();
        self.stream = None
        
if __name__ == '__main__':
    global logger
    logger = logging.getLogger("client")
    formatter = logging.Formatter("%(asctime)s; %(filename)s!%(funcName)s; %(message)s", "%Y-%m-%d %H:%M:%S")
    stderr = logging.StreamHandler()
    logfile = MyFileHandler("tmp.log",mode='a')
    stderr.setFormatter(formatter)
    logfile.setFormatter(formatter)
    logger.addHandler(stderr)
    logger.addHandler(logfile)
    logger.setLevel(logging.INFO)
    socket.setdefaulttimeout(5.0)
    sys.exit(main(sys.argv[1:]))
